package com.example.hibernate.demo.controller;

import com.example.hibernate.demo.entity.*;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import lombok.RequiredArgsConstructor;
import org.hibernate.Session;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 这个控制器展示了Hibernate的批处理和性能优化功能
 */
@RestController
@RequestMapping("/api/hibernate-performance")
@RequiredArgsConstructor
public class HibernatePerformanceController {

    @PersistenceContext
    private EntityManager entityManager;
    
    /**
     * 展示批量插入
     */
    @GetMapping("/batch-insert")
    @Transactional
    public ResponseEntity<Map<String, Object>> batchInsert() {
        Map<String, Object> result = new HashMap<>();
        
        Session session = entityManager.unwrap(Session.class);
        
        // 创建一个新部门用于批量插入员工
        Department batchDept = Department.builder()
                .name("Batch Department")
                .description("Department for batch insert demo")
                .build();
        entityManager.persist(batchDept);
        
        // 准备批量插入的员工数据
        int batchSize = 5;
        List<Employee> employees = new ArrayList<>();
        
        for (int i = 0; i < batchSize; i++) {
            Employee emp = Employee.builder()
                    .firstName("Batch")
                    .lastName("User" + i)
                    .email("batch.user" + i + "@example.com")
                    .salary(new BigDecimal("50000").add(new BigDecimal(i * 1000)))
                    .status(Employee.EmployeeStatus.ACTIVE)
                    .department(batchDept)
                    .build();
            employees.add(emp);
            
            // 每次处理一批数据
            entityManager.persist(emp);
            
            // 每批次清除会话
            if (i % 5 == 0 && i > 0) {
                entityManager.flush();
                entityManager.clear();
            }
        }
        
        result.put("batchInsertCount", batchSize);
        result.put("departmentName", batchDept.getName());
        
        return ResponseEntity.ok(result);
    }
    
    /**
     * 展示批量更新
     */
    @GetMapping("/batch-update")
    @Transactional
    public ResponseEntity<Map<String, Object>> batchUpdate() {
        Map<String, Object> result = new HashMap<>();
        
        // 使用HQL进行批量更新
        int updatedCount = entityManager.createQuery(
                "UPDATE Employee e SET e.salary = e.salary * 1.05 WHERE e.department.name = :deptName")
                .setParameter("deptName", "Batch Department")
                .executeUpdate();
        
        result.put("batchUpdateCount", updatedCount);
        
        return ResponseEntity.ok(result);
    }
    
    /**
     * 展示批量删除
     */
    @GetMapping("/batch-delete")
    @Transactional
    public ResponseEntity<Map<String, Object>> batchDelete() {
        Map<String, Object> result = new HashMap<>();
        
        // 使用HQL进行批量删除
        int deletedCount = entityManager.createQuery(
                "DELETE FROM Employee e WHERE e.firstName = :firstName")
                .setParameter("firstName", "Batch")
                .executeUpdate();
        
        result.put("batchDeleteCount", deletedCount);
        
        return ResponseEntity.ok(result);
    }
    
    /**
     * 展示分页查询
     */
    @GetMapping("/pagination")
    @Transactional(readOnly = true)
    public ResponseEntity<Map<String, Object>> pagination() {
        Map<String, Object> result = new HashMap<>();
        
        // 分页查询
        int pageSize = 10;
        int pageNumber = 0;
        
        List<Employee> page = entityManager.createQuery("FROM Employee e ORDER BY e.id", Employee.class)
                .setFirstResult(pageNumber * pageSize)
                .setMaxResults(pageSize)
                .getResultList();
        
        result.put("pageSize", pageSize);
        result.put("pageNumber", pageNumber);
        result.put("resultCount", page.size());
        
        return ResponseEntity.ok(result);
    }
}